package ai;

import board.Board;

public class Move extends AnalyseBoard{

	boolean playerStarts;
	
	//constructor
	public Move(boolean playerStarts){
		this.playerStarts = playerStarts;
	} 

	public int[] checkWhatToDo(int[][] currentBoard_refactored,int[][] currentBoard) throws couldNotFigureOutWhatToDoException{

		this.currentBoard_refactored = currentBoard_refactored; //define the global value
		int[] returnThis;
		
		if(!playerStarts && noMoveYet(currentBoard)){
			returnThis = new int[2];
			returnThis[0] = setFirstMove(currentBoard);
			returnThis[1] = returnThis[0];
			return returnThis;
		}

		returnThis = checkForFourInRowPc();
		if(returnThis[0]!=-1) return returnThis;

		returnThis = checkForfourInRowPlayer();
		if(returnThis[0]!=-1) return returnThis;

		returnThis = checkForThreeInRowPc();
		if(returnThis[0]!=-1) return returnThis;

		returnThis = checkForThreeInRowPlayer();
		if(returnThis[0]!=-1) return returnThis;

		throw new couldNotFigureOutWhatToDoException("The method figureOutWhatToDo() in Move.class could not find a preferable move");
	}

	
	//--------------------------------|
	//		   	Move methods	   	  |
	//--------------------------------|

	private boolean noMoveYet(int [][] currentBoard) {
		for(int[] lines : currentBoard){
			for(int field : lines){
				if(field != -1) return false;
			}
		}
		return true;
	}

	private int setFirstMove(int[][] board) throws boardWidthIsIlligalException{ 
		int boardWidth = -1;
		boolean isPlaced = false;
		int coord = -1;
		boardWidth = board.length;

		if(boardWidth==-1) throw new boardWidthIsIlligalException("The setFirstMethod in "+this.getClass()+" threw a new error:\nThe board width were illigal: "+board.length);

		while(!isPlaced){
			coord = (int) Math.random()*100;
			if(coord<=boardWidth) isPlaced = true;
		}

		return coord;
	}

	private int[] calm(){
		return null;
	}
	
	
	//--------------------------------|
	//				CHECKS			  |
	//--------------------------------|	

	/* About the following code
	 *These methods searches through the currentBoard_refactored for the 
	 *specified number of symbols in a row
	 */
	private int[] checkForFourInRowPc(){
		int[] nowhere = {-1,-1};
		int[] checkReturn;

		for(int i=0;i<currentBoard_refactored.length;i++){
			for(int y=0;y<currentBoard_refactored[i].length;y++){
				if(currentBoard_refactored[i][y]=='0'){
					checkReturn = analyseHoriz(y,i,0,4);
					if(checkReturn[0]!=-1 && checkReturn[2]==4) return checkReturn;
					checkReturn = analyseVert(y,i,0,4);
					if(checkReturn[0]!=-1 && checkReturn[2]==4) return checkReturn;
					checkReturn = analyseDiag1(y,i,0,4);
					if(checkReturn[0]!=-1 && checkReturn[2]==4) return checkReturn;
					checkReturn = analyseDiag2(y,i,0,4);
					if(checkReturn[0]!=-1 && checkReturn[2]==4) return checkReturn;
				}
			}
		}

		return nowhere;
	}

	private int[] checkForfourInRowPlayer(){
		int[] nowhere = {-1,-1};
		int[] checkReturn;

		for(int i=0;i<currentBoard_refactored.length;i++){
			for(int y=0;y<currentBoard_refactored[i].length;y++){
				if(currentBoard_refactored[i][y]=='1'){
					checkReturn = analyseHoriz(y,i,1,4);
					if(checkReturn[0]!=-1 && checkReturn[2]==4) return checkReturn;
					checkReturn = analyseVert(y,i,1,4);
					if(checkReturn[0]!=-1 && checkReturn[2]==4) return checkReturn;
					checkReturn = analyseDiag1(y,i,1,4);
					if(checkReturn[0]!=-1 && checkReturn[2]==4) return checkReturn;
					checkReturn = analyseDiag2(y,i,1,4);
					if(checkReturn[0]!=-1 && checkReturn[2]==4) return checkReturn;
				}
			}
		}

		return nowhere;
	}

	private int[] checkForThreeInRowPc(){
		int[] nowhere = {-1,-1};
		int[] checkReturn;

		for(int i=0;i<currentBoard_refactored.length;i++){
			for(int y=0;y<currentBoard_refactored[i].length;y++){
				if(currentBoard_refactored[i][y]=='0'){
					checkReturn = analyseHoriz(y,i,0,3);
					if(checkReturn[0]!=-1 && checkReturn[2]==3) return checkReturn;
					checkReturn = analyseVert(y,i,0,3);
					if(checkReturn[0]!=-1 && checkReturn[2]==3) return checkReturn;
					checkReturn = analyseDiag1(y,i,0,3);
					if(checkReturn[0]!=-1 && checkReturn[2]==3) return checkReturn;
					checkReturn = analyseDiag2(y,i,0,3);
					if(checkReturn[0]!=-1 && checkReturn[2]==3) return checkReturn;
					checkReturn = checkForCrossing(y,i,0,3);
					if(checkReturn[0]!=-1) return checkReturn;
				}
			}
		}

		return nowhere;
	}

	private int[] checkForThreeInRowPlayer(){
		int[] nowhere = {-1,-1};
		int[] checkReturn;

		for(int i=0;i<currentBoard_refactored.length;i++){
			for(int y=0;y<currentBoard_refactored[i].length;y++){
				if(currentBoard_refactored[i][y]=='1'){
					checkReturn = analyseHoriz(y,i,1,3);
					if(checkReturn[0]!=-1 && checkReturn[2]==3) return checkReturn;
					checkReturn = analyseVert(y,i,1,3);
					if(checkReturn[0]!=-1 && checkReturn[2]==3) return checkReturn;
					checkReturn = analyseDiag1(y,i,1,3);
					if(checkReturn[0]!=-1 && checkReturn[2]==3) return checkReturn;
					checkReturn = analyseDiag2(y,i,1,3);
					if(checkReturn[0]!=-1 && checkReturn[2]==3) return checkReturn;
					checkReturn = checkForCrossing(y,i,1,3);
					if(checkReturn[0]!=-1) return checkReturn;
				}
			}
		}

		return nowhere;
	}

	/* checkForCrossing()
	 *This method uses the diagonal test to look for crossing 3-in-a-row 
	 *and 4-in-a-row
	 *
	 *    x
	 *  /   \
	 *./     \
	 *
	 *\		/
	 * \   /
	 *	 x
	 */
	private int[] checkForCrossing(int x, int y, int c, int crossing){
		
		int[] checkReturn = analyseDiag1(x,y,c,crossing-1);
		
		int[] returnThis = new int[4]; //all checks should return a 4 field array
		returnThis[3]=0;
		returnThis[2]=0;

		if(checkReturn[0]!=-1){ //checks for legal return
			if(checkReturn[3]==1){ //there is an empty field on the top of the diag line /
				if(analyseDiag2(checkReturn[0]+1,checkReturn[1+1],c,crossing-1)[3]==1){
					returnThis[0] = checkReturn[0];
					returnThis[1] = checkReturn[1];
					return returnThis;
				}
			} else if (checkReturn[3]==-1){
				if(analyseDiag2(checkReturn[0]-1,checkReturn[1-1],c,crossing-1)[3]==-1){
					returnThis[0] = checkReturn[0];
					returnThis[1] = checkReturn[1];
					return returnThis;
				}
			}
		}

		//checks for crossing <-\->
		checkReturn = analyseDiag2(x,y,c,crossing-1);

		if(checkReturn[0]!=-1){
			if(checkReturn[3]==-1){
				if(analyseDiag1(checkReturn[0]+1,checkReturn[1-1],c,crossing-1)[3]==1){
					returnThis[0] = checkReturn[0];
					returnThis[1] = checkReturn[1];
					return returnThis;
				}
			} else if (checkReturn[3]==1){
				if(analyseDiag1(checkReturn[0]-1,checkReturn[1+1],c,crossing-1)[3]==-1){
					returnThis[0] = checkReturn[0];
					returnThis[1] = checkReturn[1];
					return returnThis;
				}
			}
		}


		return returnThis;
	}
}
